package cn.com.miao.lynx.common.core.model

import cn.com.miao.lynx.common.core.constant.CommonConstant
import cn.com.miao.lynx.common.core.constant.ResultStatus
import cn.hutool.core.util.StrUtil
import cn.hutool.json.JSONUtil
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import javax.servlet.ServletResponse

/**
 * Result
 * 公共返回类
 * @title: Result
 * @description:
 * @author: dengmiao
 * @create: 2019-12-23 11:21
 **/
class Result(var code: Int,
             var success: Boolean,
             var message: String?,
             var result: Any?){

    @Transient
    var status: HttpStatus? = null

    fun httpStatus(httpStatus: HttpStatus): Result {
        this.status = httpStatus
        return this
    }

    companion object {

        @JvmStatic
        fun ok(): Result {
            return ok(null, null)
        }

        @JvmStatic
        fun ok(message: String?): Result {
            return ok(message, null)
        }

        @JvmStatic
        fun ok(data: Any?): Result {
            return ok(null, data)
        }

        @JvmStatic
        fun ok(message: String?, data: Any?): Result {
            return restResult(HttpStatus.OK.value(), true,
                    if (StrUtil.isNotBlank(message)) {
                        message
                    } else {
                        CommonConstant.Response.SUCCESS_MSG
                    }, data)
        }

        @JvmStatic
        fun badRequest(): Result {
            var badRequest = HttpStatus.BAD_REQUEST
            return badRequest(badRequest.reasonPhrase)
        }

        @JvmStatic
        fun badRequest(message: String?): Result {
            var badRequest = HttpStatus.BAD_REQUEST
            return error(badRequest.value(), message)
        }

        @JvmStatic
        fun unauthorized(message: String?): Result {
            var unauthorized = HttpStatus.UNAUTHORIZED
            return error(unauthorized.value(), message)
        }

        @JvmStatic
        fun forbidden(message: String?): Result {
            return error(HttpStatus.FORBIDDEN.value(), message)
        }

        @JvmStatic
        fun notFound(message: String?): Result {
            return error(HttpStatus.NOT_FOUND.value(), message)
        }

        @JvmStatic
        fun methodNotAllowed(message: String?): Result {
            return error(HttpStatus.METHOD_NOT_ALLOWED.value(), message)
        }

        @JvmStatic
        fun unsupportedMediaType(message: String?): Result {
            return error(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), message)
        }

        @JvmStatic
        fun error(message: String?): Result {
            return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), message)
        }

        @JvmStatic
        fun error(code: Int, message: String?): Result {
            return restResult(code, false,
                    if (StrUtil.isNotBlank(message)) {
                        message
                    } else {
                        CommonConstant.Response.FAIL_MSG
                    }, null)
        }

        @JvmStatic
        fun error(rs: ResultStatus): Result {
            val result =  Result(rs.value, false, rs.desc, null)
            result.httpStatus(HttpStatus.INTERNAL_SERVER_ERROR)
            return result
        }

        @JvmStatic
        fun restResult(code: Int,
                       success: Boolean,
                       message: String?,
                       data: Any?): Result {
            val httpStatus = HttpStatus.valueOf(code)
            val result = Result(code, success, message, data)
            result.httpStatus(httpStatus)
            return result
        }

        @JvmStatic
        fun wrap(result: Result): ResponseEntity<Result>? {
            return result.status?.let { ResponseEntity(result, it) }
        }

        @JvmStatic
        fun response(response: ServletResponse, result: Result) {
            response.characterEncoding = "UTF-8"
            response.contentType = "application/json"
            response.writer.println(JSONUtil.toJsonStr(result))
        }
    }

}
